/*
	Base functions for voxels.
*/

#include "../../../Shared/data/cl/base.cl"

#if __CL_CPP_EMULATION__
#	define VOXEL_TEXTURE_X_FRAMES_POT		1
#	define VOXEL_TEXTURE_BORDER				1
#	define VOXEL_TEXTURE_BLOCK_SIZE_X		128
#	define VOXEL_TEXTURE_BLOCK_SIZE_Y		128
#	define VOXEL_TEXTURE_BLOCK_SIZE_Z		128
#	define PIXEL_PER_VOXEL					1
#	define VOXEL_TEXTURE_DATA_TYPE			int4
#endif


//------------------------------------------------------------------------------//
//									HEADER										//

enum
{
	_BORDER_SIZE	= VOXEL_TEXTURE_BORDER,
	_VOX_COUNT		= _BORDER_SIZE*2 + 1,
	_VOX_COUNT_2D	= _VOX_COUNT * _VOX_COUNT,
	_VOX_COUNT_3D	= _VOX_COUNT * _VOX_COUNT * _VOX_COUNT,
};

#define XYZ_TO_I( x, y, z )		((x + _BORDER_SIZE) + ((y + _BORDER_SIZE) * _VOX_COUNT) + ((z + _BORDER_SIZE) * _VOX_COUNT * _VOX_COUNT))
#define I_TO_XYZ( i )			(int3)( (i % _VOX_COUNT) - _BORDER_SIZE, ((i / _VOX_COUNT) % _VOX_COUNT) - _BORDER_SIZE, (i / _VOX_COUNT_2D) - _BORDER_SIZE )

int2 GetTexCoord (int3 coord);



//------------------------------------------------------------------------------//
//									SOURCE										//

int2 GetTexCoord (int3 coord)
{
	int3	size	= ( (int3)( VOXEL_TEXTURE_BLOCK_SIZE_X, VOXEL_TEXTURE_BLOCK_SIZE_Y, VOXEL_TEXTURE_BLOCK_SIZE_Z ) +
						2 * VOXEL_TEXTURE_BORDER ) * (int3)( PIXEL_PER_VOXEL, 1, 1 );

	int3	in_c	= clamp( ( coord + (int3)( VOXEL_TEXTURE_BORDER ) ) * (int3)( PIXEL_PER_VOXEL, 1, 1 ), (int3)(0), size );
	
	int2	c		= (int2)( in_c.z & ((1 << VOXEL_TEXTURE_X_FRAMES_POT)-1), in_c.z >> VOXEL_TEXTURE_X_FRAMES_POT ) *
					  size.xy + in_c.xy;
	return c;
}
